#ifndef IGAMESTATE_H
#define IGAMESTATE_H

#include <Ogre.h>
#include <OIS/OIS.h>

#include <boost/scoped_ptr.hpp>

#pragma warning(disable:4114)


class BaseGameManager;


//! This abstract class represents a GameState. There can be more than one active GameStates 
//! at the same time, though only one will receive input and frame events.
class IGameState
{
	BaseGameManager & mGameManager;

public:

	//! Destructor.
	//!
	virtual ~IGameState() {}

	virtual const char * GetStateName() = 0;

	//! Called when the game state is OnRegister.
	//!
	virtual void OnRegister() {}

	//! Called when the game state is entered (is added to the game state list).
	//!
	virtual void OnEnter();

	//! Called when the game state is removed from the game state list.
	//!
	//! @remark It is also called by the GameManager destructor, if the game state is active.
	virtual void OnExit() {}

	//! Called when other state becomes the main one. The GameState is still in the list and
	//! still active, but it does not receive input or frame events.
	//!
	virtual void OnPause() {}

	//! Called when, after being paused, the state recovers its main state position. After
	//! being resumed, the event will once again receive input and frame events.
	//!
	virtual void OnResume() {}

	//! Receives an event when a key is clicked.
	//! 
	virtual void OnKeyClicked(OIS::KeyEvent const & e) {}

	//! Receives an event when a key is pressed.
	//!
	virtual void OnKeyPressed(OIS::KeyEvent const & e) {}

	//! Receives an event when a key is released.
	//!
	virtual void OnKeyReleased(OIS::KeyEvent const & e) {}

	//! Receives a OnFrameStarted event.
	//!
	virtual bool OnFrameStarted(const Ogre::FrameEvent const & evt) { return true; }

	//! Receives a OnFrameEnded event.
	//!
	virtual bool OnFrameEnded(const Ogre::FrameEvent const & evt) { return true; }


	//! Receives an event when the mouse moves
	//!
	virtual bool OnMouseMoved(const OIS::MouseEvent &e) { return true; }

	//! Receives an event when a mouse button is pressed
	//!
	virtual bool OnMousePressed(const OIS::MouseEvent &e, OIS::MouseButtonID id) { return true; }

	//! Receives an event when a mouse button is released
	//!
	virtual bool OnMouseReleased(const OIS::MouseEvent &e, OIS::MouseButtonID id) { return true; }

	//! Changes the main state.
	//!
	virtual void ChangeState(IGameState * state);
	
	//! Pushes a new state, which becomes the main one.
	//!
	virtual void PushState(IGameState * state);
	
	//! Pops the currently active main state, last one is resumed.
	//!
	virtual void PopState();

	//! Returns a reference to the GameManager
	//!
	BaseGameManager & GetGameManager();


public:

	IGameState(BaseGameManager & gameManager);

};

#endif